package com.kinyx.framework.enums;

import java.util.Locale;

import com.kinyx.framework.Configs;
import com.kinyx.framework.annotation.assist.CanNull;
import com.kinyx.framework.annotation.assist.ReturnNotNull;
import com.kinyx.framework.annotation.assist.Tester;
import com.kinyx.framework.annotation.assist.Throws;
import com.kinyx.framework.enums.impl.ErrorCodeX;
import com.kinyx.framework.exception.KRuntimeException;
import com.kinyx.framework.file.KI18NUtils;

/**
 * 支持国际化的枚举定义接口
 */
@Tester("com.kinyx.framework.enums.I18NEnum_Tester")
public interface I18NEnum {

	/** @return true：忽略国际化；false：需要国际化； */
	default boolean ignoreI18N() { return false; }

	/** @return 类目名 */
	default String getCategory() { return this.getClass().getSimpleName(); }

	@ReturnNotNull
	default String getValue() {
		return this.toString().replaceAll("_", " ");
	}

	// 实现类不应修改
	@SuppressWarnings("unused")
	@ReturnNotNull
	@Throws(at = "KReader.read(InputStream, String)", value = "UnsupportedEncodingException", when = "new InputStreamReader(InputStream, String)")
	@Throws(at = "KReader.read(InputStream, String)", value = "IOException", when = "InputStreamReader.read()")
	//	@Throws(at = "KFileReader.openStream(String)", value = "ErrorCode0.FileDoesNotExists", when = "ClassLoader.getSystemResource(String) == null")
	@Throws(at = "KFileReader.openStream(String)", value = "IOException", when = "URL.openStream()")
	@Throws(at = "KPropertiesReader.read(String, String)", value = "IOException", when = "Properties.load(Reader)")
	@Throws(at = "KI18NUtils.getStringValue(Locale, String, String)", value = "ErrorCodeX.NotConfiged", when = "未配置文件或未配置值")
	default String getValue(@CanNull(defaultValue = "Configs.default_locale") final Locale locale) {
		if (locale == null) { return this.getValue(Configs.default_locale); }
		if (this instanceof IEnum_zh_CN) {// 实现了简体中文接口
			if (this.ignoreI18N()) {// 如需忽略国际化
				if (locale.getLanguage().equals(Locale.SIMPLIFIED_CHINESE.getLanguage())) {// 模糊匹配中文环境，则返回实现。
					return ((IEnum_zh_CN) this).getZh_CN();
				} else {// 其它国际化，返回默认值。
					return this.getValue();
				}
			} else {// 不忽略国际化
				if (locale.getCountry().equals(Locale.SIMPLIFIED_CHINESE.getCountry()) && locale.getLanguage().equals(Locale.SIMPLIFIED_CHINESE.getLanguage())) {// 精确匹配简体中文环境，返回实现。
					return ((IEnum_zh_CN) this).getZh_CN();
				} else {// 其它国际化，从配置文件中取。
					// 因为可能配置了国际化文件，则优先取文件中的值。 GOTO load
					// 如配置文件取不到时，再尝试模糊匹配中文环境。 GOTO fuzzy
				}
			}
		} else {// 未实现简体中文接口
			if (this.ignoreI18N()) {// 如需忽略国际化，返回默认值。
				return this.getValue();
			} else {// 不忽略国际化，从配置文件中取。GOTO load
			}
		}

		load: try {
			// 从配置文件中取
			return KI18NUtils.getStringValue(locale, this.getCategory(), this.toString());
		} catch (final KRuntimeException e) {
			// 该放发会尝试精确匹配，失败后再尝试模糊匹配，仍然失败才会抛出NotConfiged异常。
			// 其它异常需要抛出
			if (!e.getErrorCode().equals(ErrorCodeX.NotConfiged)) { throw e; }
			// 未配置文件或未配置值
			fuzzy: if ((this instanceof IEnum_zh_CN) && locale.getLanguage().equals(Locale.SIMPLIFIED_CHINESE.getLanguage())) {// 模糊匹配中文环境，则返回实现。
				return ((IEnum_zh_CN) this).getZh_CN();
			}
			return this.getValue();// 其它情况，返回默认值。
		}
	}

}
